package com.bpvse;


import com.util.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Base64;
import java.util.Map;

@Service
public class VerifyService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    private static final byte[] strEOF = new byte[]{69, 79, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    public boolean verify(int resultLen, int astLen) {
        int i, j;
        int index;
        int tmpR;

        byte[] IH = new byte[DataUnit.HASH_LEN];
        byte[] hd = new byte[DataUnit.HASH_LEN];
        byte[] tmp = new byte[DataUnit.HASH_LEN];
        byte[] st = new byte[DataUnit.HASH_LEN];
        byte[] Pv1 = new byte[DataUnit.HASH_LEN];
        byte[] Pv2 = new byte[DataUnit.HASH_LEN];
        byte[] Pv2T = new byte[DataUnit.HASH_LEN];
        byte[] st2Message = new byte[DataUnit.HASH_LEN];
        byte[] IHMessage = new byte[DataUnit.HASH_LEN];

        index = resultLen;

        try {
            System.arraycopy(strEOF, 0, Pv1, 0, DataUnit.HASH_LEN);
            System.out.println("Pv1的内容是"+Arrays.toString(Pv1));

            //StoreUnit.SR.get(astLen - 1).getBytes()该方法将字符串变成byte[]
            System.out.println("StoreUnit.SR.get(astLen - 1).getBytes()里面的内容是:"+ Arrays.toString(Base64.getDecoder().decode(StoreUnit.SR.get(astLen - 1))));
            System.arraycopy(Base64.getDecoder().decode(StoreUnit.SR.get(astLen - 1)), 0, st, 0, DataUnit.HASH_LEN); // st_1
            System.out.println("st的内容是"+Arrays.toString(st));

            //tmpR的内容是一个版本号version,对应的索引iDB
            tmpR = StoreUnit.RN.get(astLen - 1);
            System.out.println("tmpR的内容是:"+tmpR);

            for (i = 0; i < tmpR; i++) {
                System.out.println("StoreUnit.TR.get(index - tmpR + i).getBytes()里面的内容是:"+Arrays.toString(Base64.getDecoder().decode(StoreUnit.TR.get(index - tmpR + i)))); //找到strv
                System.arraycopy(Base64.getDecoder().decode(StoreUnit.TR.get(index - tmpR + i)), 0, tmp, 0, Base64.getDecoder().decode(StoreUnit.TR.get(index - tmpR + i)).length );
                addHashUnit.addHash(IH, IH, tmp, DataUnit.HASH_LEN);
            }

            System.arraycopy(IH, 0, hd, 0, DataUnit.HASH_LEN);
            hkeyUnit.hkey(Pv2, hd, Pv1, DataUnit.HASH_LEN, st, DataUnit.HASH_LEN);
            System.out.println("Pv2加密的值："+Base64.getEncoder().encodeToString(Pv2));  //获得第一次更新的加密值

            //4-2
            index = resultLen - tmpR;

            //如果更新不止一次的话，需要循环进入，依次获得后面的pv值，如果就一次的话，不需要循环操作了.
            for (i = astLen - 2; i >= 0; i--) {
                System.arraycopy(Pv2, 0, Pv1, 0, Pv2.length);
                resetUnit.reset(Pv2,DataUnit.HASH_LEN); //重制Pv2,方便后面计算下一步的pv值
                System.out.println("StoreUnit.SR.get(i).getBytes()的内容是:"+Arrays.toString(Base64.getDecoder().decode(StoreUnit.SR.get(i))));  //最新一次的状态
                System.arraycopy(Base64.getDecoder().decode(StoreUnit.SR.get(i)), 0, st, 0,  DataUnit.HASH_LEN); // st_2,3,4,....
                tmpR = StoreUnit.RN.get(i);   //对应版本文件的次数
                resetUnit.reset(IH, DataUnit.HASH_LEN);

                //最新一次的结果
                for (j = 0; j < tmpR; j++) {
                    //获得下一版本的搜索结果
                    System.out.println("StoreUnit.TR.get(index - tmpR + j).getBytes()的内容是:"+Arrays.toString(Base64.getDecoder().decode(StoreUnit.TR.get(index - tmpR + j))));
                    System.arraycopy(Base64.getDecoder().decode(StoreUnit.TR.get(index - tmpR + j)), 0, tmp, 0,  Base64.getDecoder().decode(StoreUnit.TR.get(index - tmpR + j)).length);
                    addHashUnit.addHash(IH, IH, tmp, DataUnit.HASH_LEN);
                }
                System.arraycopy(IH, 0, hd, 0, DataUnit.HASH_LEN);

                //根据Pv1计算出Pv2
                hkeyUnit.hkey(Pv2, hd, Pv1, DataUnit.HASH_LEN, st, DataUnit.HASH_LEN);  //通过pv0->pv1->pv2...计算出最新版本的pv值
                System.out.println("Pv2的内容是:"+Arrays.toString(Pv2));
                System.out.println("Pv2的字符串值是"+Base64.getEncoder().encodeToString(Pv2));
                index = index - tmpR;
            }

            System.out.println("StoreUnit.SR.get(0).getBytes()的内容是:"+Arrays.toString(Base64.getDecoder().decode(StoreUnit.SR.get(0))));  //获得最新版本的st

            System.arraycopy(Base64.getDecoder().decode(StoreUnit.SR.get(0)), 0, st2Message, 0, Base64.getDecoder().decode(StoreUnit.SR.get(0)).length);
            //计算出pa2
            hUnit.h(tmp, st2Message, DataUnit.HASH_LEN, (byte) 0);  //计算出最新版本的pa

            //根据pa2获得pv2T
            String redisKey = Base64.getEncoder().encodeToString(tmp);
            System.out.println("redisKey的值"+redisKey);
            String reply = stringRedisTemplate.opsForValue().get(redisKey);  //对应的字符串值
            System.out.println("PV2T的值是:"+reply);

            if (reply != null) {
                Pv2T = Base64.getDecoder().decode(reply);
               // System.out.println("PV2t加密的值："+ Base64.getEncoder().encodeToString(Pv2T));
            } else {
                System.out.println("verify-error!");
                return false;
            }
            //计算出来的pv值和reids里面获得的pv值是否相同
            if (strequalUnit.strequal(Pv2, Pv2T, DataUnit.HASH_LEN)) {
                return true;
            }
        } catch (Exception e) {
            System.out.println("connection error: " + e.getMessage());
            return false;
        }

        return false;
    }

}
